package impl.ui;

import interfaces.ListListener;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import candySystemNamespace.CandyWorld;
import classes.Constants;
import classes.Utils;

public class MainWindow extends JFrame implements ActionListener, ListListener {
	private final String TAG = Constants.TAG + "." + getClass().getSimpleName();
	
	private static final long serialVersionUID = -5302944792496072970L;
	
	private JButton[] controls = new JButton[4];
	
	private JLabel[] legendLabels = new JLabel[4];
	
	/** Image resource loader */
	private ClassLoader classLoader;
	
	/** The view with all the elements */
	private MapView mapView;
	
	/** The CandyWorld */
	private CandyWorld.Component candyWorld;
	
	public MainWindow(int candyNumber, int robotNumber, CandyWorld.Component candyWorld) {
		Utils.logC(TAG, "creating window");
		
		classLoader = getClass().getClassLoader();

		try {
			init(candyNumber, robotNumber, candyWorld);
		} catch (Exception e) {
			Utils.logC(TAG, "Failed to initialize: " + e.getMessage());
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, "Failed to start CandyWorld: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			dispose();
		}
	}
	
	private void init(int candies, int robots, CandyWorld.Component candyWorld) {
		int screenHeight = getToolkit().getScreenSize().height;
		int screenWidth = getToolkit().getScreenSize().width;

		setLayout(new GridBagLayout());
		
		GridBagConstraints constrains = new GridBagConstraints();
		constrains.fill = GridBagConstraints.HORIZONTAL;
		constrains.gridx = 0;
		constrains.gridy = 0;
		constrains.weightx = 1;
		constrains.weighty = 0;
		constrains.anchor = GridBagConstraints.NORTH;
		constrains.insets = new Insets(5, 20, 5, 20);
		
		controls[0] = new JButton(Constants.MAIN_PLAY_BUTTON, new ImageIcon(classLoader.getResource("play.png")));
		controls[0].addActionListener(this);
	    add(controls[0], constrains);
	    
	    controls[1] = new JButton(Constants.MAIN_PAUSE_BUTTON, new ImageIcon(classLoader.getResource("pause.png")));
	    controls[1].addActionListener(this);
	    constrains.gridx++;
	    add(controls[1], constrains);
	    
	    controls[2] = new JButton(Constants.MAIN_RESET_BUTTON, new ImageIcon(classLoader.getResource("stop.png")));
	    controls[2].addActionListener(this);
	    constrains.gridx++;
	    add(controls[2], constrains);
	    
	    controls[3] = new JButton(Constants.MAIN_STEP_BUTTON, new ImageIcon(classLoader.getResource("step.png")));
	    controls[3].addActionListener(this);
	    constrains.gridx++;
	    add(controls[3], constrains);
	    
	    mapView = new MapView(Constants.MAP_WIDTH, Constants.MAP_HEIGHT);
	    constrains.gridy = 1;
	    constrains.gridx = 0;
	    constrains.gridwidth = 4;
	    constrains.weighty = 1;
	    constrains.fill = GridBagConstraints.BOTH;
	    constrains.anchor = GridBagConstraints.SOUTH;
	    add(mapView, constrains);
	    
	  //Add legend to layout
	  		legendLabels[0] = new JLabel("Candy Tile");
	  		legendLabels[0].setForeground(new Color(Constants.MAIN_CANDY_COLOR));
	  	    constrains.gridy = 2;
	  	    constrains.gridx = 0;
	  	    constrains.gridwidth = 4;
	  	    constrains.weighty = 0;
	  	    constrains.fill = GridBagConstraints.HORIZONTAL;
	  		constrains.anchor = GridBagConstraints.SOUTHWEST;
	  		add(legendLabels[0], constrains);
	  		
	  		legendLabels[1] = new JLabel("Obstacol Tile");
	  		legendLabels[1].setForeground(new Color(Constants.MAIN_OBSTACLE_COLOR));
	  		constrains.gridx++;
	  		add(legendLabels[1], constrains);
	  		
	  		legendLabels[2] = new JLabel("Robot with Candy Tile");
	  		legendLabels[2].setForeground(new Color(Constants.MAIN_ROBOT_WITH_CANDY_COLOR));
	  		constrains.gridx++;
	  		add(legendLabels[2], constrains);
	  		
	  		legendLabels[3] = new JLabel("Robot Tile");
	  	    legendLabels[3].setForeground(new Color(Constants.MAIN_ROBOT_COLOR));
	  		constrains.gridx++;
	  		add(legendLabels[3], constrains);
		
		// Rest of windows settings
		setLocation(screenWidth / 2 - Constants.MAIN_WIDTH / 2, screenHeight / 2 - Constants.MAIN_HEIGHT / 2);
		setVisible(true);
		setSize(Constants.MAIN_WIDTH, Constants.MAIN_HEIGHT);
		setResizable(false);
		setTitle(Constants.TAG);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		this.candyWorld = candyWorld;
		candyWorld.resources().getFreePositions().addListener(this);
		candyWorld.resources().getCandiesPositions().addListener(this);
		candyWorld.robotsInfo().getRobotsInfo().addListener(this);
		
		mapView.setViews(candyWorld.resources().getFreePositions(), candyWorld.resources().getCandiesPositions(), candyWorld.robotsInfo());
	}
	
	@Override
	public void actionPerformed(ActionEvent event) {
		String button = event.getActionCommand();
		Utils.logC(TAG, "Button clicked: " + button);
		
		if (button.equals(Constants.MAIN_PLAY_BUTTON)) {
			Utils.logC(TAG, "Playing the world");
			controls[0].setEnabled(false);
			controls[3].setEnabled(false);
		} else if (button.equals(Constants.MAIN_PAUSE_BUTTON)) {
			Utils.logC(TAG, "Playing the world");
			controls[0].setEnabled(true);
			controls[1].setEnabled(false);
			controls[3].setEnabled(true);
		} else if (button.equals(Constants.MAIN_RESET_BUTTON)) {
			Utils.logC(TAG, "Playing the world");
			controls[0].setEnabled(true);
			controls[1].setEnabled(true);
			controls[3].setEnabled(true);
		} else if (button.equals(Constants.MAIN_STEP_BUTTON)) {
			Utils.logC(TAG, "Step");
		} else {
			Utils.logC(TAG, "Unknown button clicked");
		}
	}

	@Override
	public void onListChanged() {
		Utils.logC(TAG, "Something changed in the world");
		
		mapView.setViews(candyWorld.resources().getFreePositions(), candyWorld.resources().getCandiesPositions(), candyWorld.robotsInfo());
	}

}
